from csv import writer as csvWriter
from time import time as now
from re import findall as findPlayers

input_file = "./match2.txt"
output_file = "./match2.csv"

stats_5 = 1
stats_6 = 2
stats_7 = 3
stats_8 = 4
stats_9 = 5
stats_10 = 6
stats_11 = 7
stats_12 = 8
stats_hit_broadcasted = 9
stats_hits = 10
stats_death = 11
stats_kill = 12
stats_team = 13
stats_actor_p_main = 14
stats_actor_p_scnd = 15
stats_score = 16
stats_max_index = 16

stats_first_row = ["ID","五连击","六连击","七连击","八连击","九连击","十连击","十一连击","十二连击","连击广播次数","保留","阵亡次数","击杀数","队伍ID","常用角色","次要常用角色","总得分"]

weapons = ["喵的末路","圣剑","角斗士的终幕礼","翡翠之弩","末日拳套","猎杀者匕首 | (★)","埃提耶什","光明权杖","PRTS 代理作战终端"]
professions = ["毛妹","吉塔","大锤","全藏","铁拳","刺客","麦迪文","天使","刀客塔"]

# 假定制造11~12连击得分为5
points = [1,1,1,2,2,2,3,3,4,4,5,5]


class Stats():
  players = {}
  actors = []

  def __init__(self) -> None:
      i = 0
      while(i<len(weapons)):
        p_count = {}
        self.actors.append(p_count)
        i+=1
      pass

  def create(self,pid):
    player = []
    player.append(pid)
    for i in range(1,stats_max_index+1):
      if (i==stats_actor_p_main) or (i==stats_actor_p_scnd):
        player.append("无")
      else:
        player.append(0)
    self.players[pid]=player
    
  def death(self,pid,gg=False):
    if(pid not in self.players):
      self.create(pid)
    player=self.players[pid]
    # 死亡/比赛结束时，归结本轮连击杀敌数
    i = player[stats_hits]
    if (i>=5):
      player[i-4] += 1
    player[stats_hits]=0
    if (gg==False):
      # 比赛期间计算死亡数
      player[stats_death]+=1
    else:
      # 比赛结束时，归结最常用的两个职业
      j=0
      p1=len(professions)+1
      p2=p1
      pc1=0
      pc2=0
      for actor in self.actors:
        if(pid in actor):
          if (pc1<actor[pid]):
            p2 = p1
            p1 = j
            pc2 = pc1
            pc1 = actor[pid]
          elif (pc2<actor[pid]) and (p1!=j):
            pc2 = actor[pid]
            p2 = j
        j+=1
      if (p1==len(professions)+1):
        player[stats_actor_p_main]='N/A'
      else:
        player[stats_actor_p_main]=professions[p1]
      if (p2==len(professions)+1):
        player[stats_actor_p_scnd]='N/A'
      else:
        player[stats_actor_p_scnd]=professions[p2]


  def kill(self,pid,weapon):
    if(pid not in self.players):
      self.create(pid)
    player=self.players[pid]
    # 统计击杀得分
    i = player[stats_hits]
    if (i>=12):
      i=11
    player[stats_score] += points[i]
    if (weapon in weapons):
      # 统计使用武器次数，以确定常用职业
      i = weapons.index(weapon)
      p_count = self.actors[i]
      if (pid not in p_count):
        p_count[pid] = 1
      else:
        p_count[pid] += 1
    # 统计总杀敌数，与本轮连击杀敌数
    player[stats_hits] += 1
    player[stats_kill] += 1
    if(player[stats_hits]>=5):
      player[stats_hit_broadcasted] +=1


class LogHandler():
  stats = Stats()
  battle_count = 0
  multihit_broadcast = 0

  def __init__(self) -> None:
      pass

  def parseLine(self,line):
    players = findPlayers("\?\s[A-Za-z0-9_]+",line)
    if(len(players)==0) or (len(players)>=3):
      return
    self.battle_count+=1
    if(len(players)==2):
      # 移除log击杀信息内的“? ”（原为队伍编号，在log保存到硬盘期间被消除）
      player1 = players[0][2:]
      player2 = players[1][2:]
      # 一条“A被B用[武器]击败了”等有两名玩家的消息
      self.stats.death(player1)
      weapon = "无"
      w1 = line.rfind('[')
      w2 = line.rfind(']')
      if(w1>=32) and (w2>=32):
        weapon = line[w1+1:w2]
      self.stats.kill(player2,weapon)
    else:
      # 一条仅含一名玩家的消息，包括“A掉出了世界”“A被闪电击中”等；但不包括“A连续击败”
      player = players[0][2:]
      if(line.find('续击')>=0):
        self.multihit_broadcast+=1
        return
      self.stats.death(player)

  def goodGame(self):
    print('Record battle events:',self.battle_count)
    print('including multi-hit broadcasts in total of',self.multihit_broadcast)
    print('Participants count:',len(self.stats.players.keys()))
    for player in self.stats.players.keys():
      self.stats.death(player,True)

  def parseFile(self,path):
    with open(path,'r',encoding='utf-8') as f:
      lines = f.readlines()
      print('Read lines',len(lines))
      for line in lines:
        self.parseLine(line)
      self.goodGame()
      f.close()
    csv_file = open(output_file,'w',newline='',encoding='gb18030')
    writer = csvWriter(csv_file)
    writer.writerow(stats_first_row)
    iteration = iter(self.stats.players.values())
    writer.writerows(iteration)
    csv_file.close()

if __name__=='__main__':
  h = LogHandler()
  time_start = now()
  h.parseFile(input_file)
  time_end = now()
  ellapse = time_end-time_start
  print("It took",ellapse,"sec to run")